package com.zyl.blog.tasks.schedule.manager;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.zyl.blog.common.domain.task.bean.TaskInfo;
import com.zyl.blog.common.domain.task.vo.TaskOperationResult;
import com.zyl.blog.common.exception.BlogException;
import com.zyl.blog.common.utils.Extreme.LogUtil;
import com.zyl.blog.tasks.enums.TaskType;
import com.zyl.blog.tasks.exception.TaskAlreadyExistsException;
import com.zyl.blog.tasks.exception.TaskNotFoundException;
import com.zyl.blog.tasks.exception.TaskOperationException;
import com.zyl.blog.tasks.mapper.TaskInfoMapper;
import com.zyl.blog.tasks.schedule.abstracts.AbstractScheduledTask;
import com.zyl.blog.tasks.schedule.container.TaskContainer;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.context.ApplicationContext;
import org.springframework.scheduling.support.CronExpression;
import org.springframework.scheduling.support.CronTrigger;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import java.lang.reflect.InvocationTargetException;
import java.time.Duration;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.*;
import java.util.stream.Collectors;

/**
 * @version v1.0
 * @ProjectName: Personal_Blog_Server
 * @Package: com.zyl.blog.tasks.schedule.manager
 * @ClassName: TaskManagerImpl
 * @Description:
 * @Author FinalFantasy
 * @Date 2025/8/12-10:34
 */
@Component
@RequiredArgsConstructor
public class TaskManagerImpl implements TaskManager {

    private final TaskContainer taskContainer;
    private final ApplicationContext applicationContext;
    private final TaskInfoMapper taskInfoMapper;

    /* 虚拟线程池（JDK24+特性，轻量级线程提升批量处理性能） */
    private final ExecutorService virtualThreadPool = Executors.newThreadPerTaskExecutor(
            Thread.ofVirtual().name("batch-task-").factory()
    );

    /**
     * 初始化时扫描并注册所有任务（使用虚拟线程并发执行，提升性能）
     */
    @PostConstruct
    @Override
    public void scanAndRegisterTasks() {
        LogUtil.info("[任务注册] 开始扫描并注册所有任务...");

        /* 获取所有AbstractScheduledTask的实现类 */
        Map<String, AbstractScheduledTask> taskBeans = applicationContext.getBeansOfType(AbstractScheduledTask.class);
        LogUtil.info("[任务注册] 扫描到 [{}] 个任务Bean待注册", taskBeans.size());

        if (taskBeans.isEmpty()) {
            LogUtil.info("[任务注册] 无任务需要注册，流程结束");
            return;
        }

        /* 使用虚拟线程池并发执行任务注册（避免同步阻塞） */
        List<CompletableFuture<Void>> futures = taskBeans.values().stream()
                .map(task -> CompletableFuture.runAsync(
                        () -> processTaskOnStartup(task), // 处理单个任务（区分首次注册和重复加载）
                        virtualThreadPool
                ).exceptionally(ex -> {
                    /* 单个任务注册失败不影响整体，单独记录异常 */
                    LogUtil.error("[任务注册] 任务[{}]注册失败（所属用户：[{}]）",
                            null, task.getTaskName(), task.getUsername(), ex);
                    return null;
                }))
                .toList();

        /* 等待所有注册任务完成 */
        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();
        LogUtil.info("[任务注册] 所有任务注册流程已完成");
    }

    /**
     * 启动时处理单个任务（核心优化：区分注册、加载、恢复逻辑）
     */
    private void processTaskOnStartup(AbstractScheduledTask task) {
        String taskName = task.getTaskName();
        String username = task.getUsername();
        LogUtil.info("[任务处理] 开始处理任务 - 名称：[{}]，所属用户：[{}]", taskName, username);

        try {
            /* 检查数据库中是否已存在该任务 */
            Optional<TaskInfo> existingTask = taskInfoMapper.findTaskByDoubleName(taskName, username, false);

            if (existingTask.isPresent()) {
                /* 数据库已存在：仅加载到内存容器，无需重复入库 */
                loadExistingTaskToContainer(task, existingTask.get());
            } else {
                /* 数据库不存在：执行完整注册流程（入库+入容器） */
                registerAndPersistTask(task);
            }

        } catch (Exception e) {
            LogUtil.error("[任务处理] 任务[{}]处理失败（所属用户：[{}]）",
                    null, taskName, username, e);
            /* 清理可能的脏数据 */
            taskContainer.removeTask(taskName, username);
        }
    }

    /**
     * 注册并持久化任务（补充详细日志，规范格式）
     */
    private void registerAndPersistTask(AbstractScheduledTask task) {
        String taskName = task.getTaskName();
        String username = task.getUsername();
        TaskType scheduleType = task.getScheduleType();

        LogUtil.info("[任务注册] 开始处理任务 - 名称：[{}]，所属用户：[{}]，类型：[{}]",
                taskName, username, scheduleType);

        /* 先注册到容器 */
        taskContainer.addTask(task);
        LogUtil.debug("[任务注册] 任务[{}]已添加到内存容器", taskName);

        /* 持久化到数据库（检查是否已存在，避免重复插入） */
        /* 更新现有任务信息 */
        TaskInfo taskInfo = new TaskInfo()
                .setTaskName(taskName)
                .setTaskDescription(task.getTaskDescription())
                .setScheduleType(scheduleType.name())
                .setCronExpression(task.getCronExpression())
                .setTaskInterval(task.getTaskInterval())
                .setTimeUnit(task.getTimeUnit().name())
                .setUsername(username)
                .setTaskClassName(task.getClassName())
                .setIsActive(task.startBoot() ? 1 : 0)  // 新任务默认未激活， 由startBoot决定是否启动
                .setCreateTime(LocalDateTime.now());

        taskInfoMapper.insert(taskInfo);

        LogUtil.info("[任务注册] 任务[{}]已新增到数据库", taskName);

        /* 打印任务核心参数（区分调度类型显示） */
        String paramsLog = buildTaskParamsLog(scheduleType, task);
        LogUtil.info("[任务注册] 新任务注册完成 - {}", paramsLog);
    }

    @Override
    @Transactional
    public TaskOperationResult registerTask(AbstractScheduledTask task) {
        try {
            /* 检查是否存在未删除的同名任务 */
            boolean exists = taskInfoMapper.exists(
                    new LambdaQueryWrapper<TaskInfo>()
                            .eq(TaskInfo::getTaskName, task.getTaskName())
                            .eq(TaskInfo::getUsername, task.getUsername())
            );
            if (exists) {
                throw new TaskAlreadyExistsException("任务 " + task.getTaskName() + "已存在, 无法重复注册");
            }

            registerAndPersistTask(task);

            return new TaskOperationResult(true, "任务注册成功", task.getTaskName());
        } catch (Exception e) {
            return new TaskOperationResult(false, "任务注册失败: " + e.getMessage(), task.getTaskName());
        }
    }

    @Override
    @Transactional
    public TaskOperationResult restoreTask(String taskName, String username) {
        try {
            /* 恢复数据库中的任务记录 */
            int affected = taskInfoMapper.restoreTask(taskName, username);
            if (affected == 0) {
                LogUtil.error("任务[{}]不存在或未被删除", null, taskName);
                return new TaskOperationResult(false, "任务不存在或未被删除", taskName);
            }

            /* 从数据库加载任务信息 */
            TaskInfo taskInfo = taskInfoMapper.findTaskByDoubleName(taskName, username, true)
                    .orElseThrow(() -> new TaskNotFoundException("任务信息不存在: " + taskName));

            /* 反射创建任务实例 */
            Class<?> taskClass = Class.forName(taskInfo.getTaskClassName());
            AbstractScheduledTask task = (AbstractScheduledTask) taskClass.getDeclaredConstructor().newInstance();

            /* 添加到容器 */
            taskContainer.addTask(task);

            LogUtil.info("任务[{}]恢复成功", taskName);
            return new TaskOperationResult(true, "任务恢复成功", taskName);
        } catch (Exception e) {
            LogUtil.error("任务[{}]恢复成功", null, taskName);
            return new TaskOperationResult(false, "任务恢复失败: " + e.getMessage(), taskName);
        }
    }

    @Override
    @Transactional
    public TaskOperationResult startTask(String taskName, String username) {
        try {
            /* 检查任务是否已在运行 */
            if (isTaskRunning(taskName, username)) {
                return new TaskOperationResult(false, "任务已在运行中", taskName);
            }

            /* 获取任务 */
            AbstractScheduledTask task = taskContainer.getTask(taskName, username);
            if (task == null) {
                throw new TaskNotFoundException("任务不存在: " + taskName);
            }

            /* 根据调度类型启动任务 */
            ScheduledFuture<?> scheduledTask = (ScheduledFuture<?>) scheduleTask(task);

            /* 存储运行中的任务 */
            taskContainer.storeRunningTask(taskName, username, scheduledTask);

            /* 更新任务状态 */
            updateTaskStatus(taskName, username, 1);

            return new TaskOperationResult(true, "任务启动成功", taskName);
        } catch (Exception e) {
            return new TaskOperationResult(false, "任务启动失败: " + e.getMessage(), taskName);
        }
    }

    /**
     * 根据任务类型调度任务
     */
    private Object scheduleTask(AbstractScheduledTask task) {
        return switch (task.getScheduleType()) {
            case CRON -> scheduleCronTask(task);
            case FIXED_RATE -> scheduleFixedRateTask(task);
            case FIXED_DELAY -> scheduleFixedDelayTask(task);
        };
    }

    /**
     * 调度CRON任务
     */
    private ScheduledFuture<?> scheduleCronTask(AbstractScheduledTask task) {
        String cronExpression = task.getCronExpression();
        if (cronExpression == null || cronExpression.trim().isEmpty()) {
            throw new TaskOperationException("CRON表达式不能为空");
        }

        /* 创建CronTrigger触发器，使用正确的方式 */
        CronTrigger cronTrigger = new CronTrigger(cronExpression);

        return taskContainer.getTaskScheduler().schedule(
                createTaskRunnable(task),
                cronTrigger
        );
    }


    /**
     * 调度固定速率任务
     */
    private ScheduledFuture<?> scheduleFixedRateTask(AbstractScheduledTask task) {
        return taskContainer.getTaskScheduler().scheduleAtFixedRate(
                createTaskRunnable(task),
                Duration.of(task.getTaskInterval(), task.getTimeUnit())
        );
    }

    /**
     * 调度固定延迟任务
     */
    private ScheduledFuture<?> scheduleFixedDelayTask(AbstractScheduledTask task) {
        return taskContainer.getTaskScheduler().scheduleWithFixedDelay(
                createTaskRunnable(task),
                Duration.of(task.getTaskInterval(), task.getTimeUnit())
        );
    }

    /**
     * 创建任务执行的Runnable，使用JDK24虚拟线程特性
     */
    private Runnable createTaskRunnable(AbstractScheduledTask task) {

        return () -> {
            long start = System.currentTimeMillis();

            try {
                task.execute();
            } catch (Exception e) {
                LogUtil.error("[任务执行] 任务[{}]执行失败（所属用户：[{}]）",
                        null, task.getTaskName(), task.getUsername(), e);
            } finally {
                long cost = System.currentTimeMillis() - start;
                LogUtil.info("[任务执行] 任务[{}]执行完成，耗时：{}ms", task.getTaskName(), cost);
            }
        };

        /* 使用JDK24的虚拟线程 */
//        return Thread.ofVirtual()
//                .name("task-" + task.getUsername() + "-" + task.getTaskName())
//                .unstarted(task::execute);
    }

    @Override
    @Transactional
    public TaskOperationResult pauseTask(String taskName, String username) {
        try {
            /* 检查任务是否在运行 */
            ScheduledFuture<?> scheduledTask = taskContainer.getRunningTask(taskName, username);
            if (scheduledTask == null) {
                return new TaskOperationResult(false, "任务未在运行中", taskName);
            }

            /* 取消任务 */
            scheduledTask.cancel(true);

            /* 从运行任务中移除 */
            taskContainer.removeRunningTask(taskName, username);

            /* 更新任务状态 */
            updateTaskStatus(taskName, username, 0);

            return new TaskOperationResult(true, "任务暂停成功", taskName);
        } catch (Exception e) {
            return new TaskOperationResult(false, "任务暂停失败: " + e.getMessage(), taskName);
        }
    }

    @Override
    @Transactional(rollbackFor = BlogException.class)
    public TaskOperationResult destroyTask(String taskName, String username, Boolean status) {
        try {
            /* 先暂停任务 */
            TaskOperationResult pauseResult = pauseTask(taskName, username);
            if (!pauseResult.getSuccess() && !"任务未在运行中".equals(pauseResult.getMessage())) {
                return pauseResult;
            }

            /* 从容器中移除任务 */
            taskContainer.removeTask(taskName, username);

            /* 根据标志位判断是否需要物理或逻辑删除 */
            int affected = status ?
                    taskInfoMapper.logicDeleteTask(taskName, username) : taskInfoMapper.physicalDeleteTask(taskName, username);

            if (affected == 0) {
                LogUtil.error("任务[{}]不存在或已经被删除", null, taskName);
                return new TaskOperationResult(false, "任务不存在或已经被删除", taskName);
            }

            LogUtil.info("任务[{}]销毁成功", taskName);
            return new TaskOperationResult(true, "任务销毁成功", taskName);
        } catch (Exception e) {
            LogUtil.error("任务[{}]销毁失败", null, taskName);
            return new TaskOperationResult(false, "任务销毁失败: " + e.getMessage(), taskName);
        }
    }

    @Override
    @Transactional(rollbackFor = BlogException.class)
    public TaskOperationResult reloadTask(String taskName, String username) {
        try {
            /* 先销毁现有任务(true) -> 物理删除 -> 从数据库重新插入一遍 */
            destroyTask(taskName, username, false);

            /* 反射创建新的任务实例 */
            TaskInfo taskInfo = taskInfoMapper.findTaskByDoubleName(taskName, username, false)
                    .orElseThrow(() -> new TaskNotFoundException("任务信息不存在: " + taskName));

            Class<?> taskClass = Class.forName(taskInfo.getTaskClassName());
            AbstractScheduledTask task = (AbstractScheduledTask) taskClass.getDeclaredConstructor().newInstance();

            /* 重新注册并启动任务 */
            registerTask(task);
            return startTask(taskName, username);
        } catch (Exception e) {
            return new TaskOperationResult(false, "任务重新加载失败: " + e.getMessage(), taskName);
        }
    }

    @Override
    public List<AbstractScheduledTask> getUserTasks(String username) {
        return taskContainer.getUserTasks(username);
    }

    @Override
    public boolean isTaskRunning(String taskName, String username) {
        return taskContainer.getRunningTask(taskName, username) != null;
    }

    @Override
    public List<AbstractScheduledTask> getUserAllTasks(String username) {
        /* 从数据库查询用户所有任务记录（包括已删除）不能用plus方法，因为plus方法会把已删除（逻辑删除）的任务过滤 */
        List<TaskInfo> allTaskInfos = taskInfoMapper.findByUsername(username);

        /* 转换为任务实例列表 */
        return allTaskInfos.stream()
                .map(this::convertToTaskInstance)
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
    }

    /**
     * 将TaskInfo转换为AbstractScheduledTask实例
     */
    private AbstractScheduledTask convertToTaskInstance(TaskInfo taskInfo) {
        try {
            /* 通过类名反射创建实例 */
            Class<?> taskClass = Class.forName(taskInfo.getTaskClassName());
            AbstractScheduledTask task = (AbstractScheduledTask) taskClass.getDeclaredConstructor().newInstance();

            /* 恢复任务的基本信息 */
            /* （需要在AbstractScheduledTask中添加setter方法或通过反射设置字段） */
            setTaskField(task, "taskName", taskInfo.getTaskName());
            setTaskField(task, "username", taskInfo.getUsername());

            return task;
        } catch (Exception e) {
            /* 记录转换失败日志，可能是任务类已被删除 */
            LogUtil.error("转换任务实例失败，任务名称: {}, 类名: {}", null,
                    taskInfo.getTaskName(), taskInfo.getTaskClassName(), e);
            return null;
        }
    }

    /**
     * 通过反射设置任务字段值
     */
    private void setTaskField(AbstractScheduledTask task, String fieldName, Object value) throws Exception {
        java.lang.reflect.Field field = task.getClass().getDeclaredField(fieldName);
        field.setAccessible(true);
        field.set(task, value);
    }

    /**
     * 更新任务状态
     */
    private void updateTaskStatus(String taskName, String username, Integer isActive) {
        taskInfoMapper.findTaskByDoubleName(taskName, username, true)
                .ifPresent(taskInfo -> {
                    taskInfo.setIsActive(isActive);
                    taskInfoMapper.updateById(taskInfo);
                });
    }

    // ==================== 任务调度策略修改 ====================
    @Override
    @Transactional(rollbackFor = Exception.class)
    public TaskOperationResult updateTaskSchedule(
            String taskName,
            String username,
            TaskType newScheduleType,
            String cronExpression,
            Long interval,
            ChronoUnit timeUnit
    ) {

        /* 参数合法性二次校验（避免前端校验被绕过） */
        validateScheduleParams(newScheduleType, cronExpression, interval, timeUnit);

        /* 查询任务信息（检查存在性和归属） */
        TaskInfo taskInfo = taskInfoMapper.findTaskByDoubleName(taskName, username, true)
                .orElseThrow(() -> new TaskNotFoundException("任务不存在或已被删除：" + taskName));

        /* 检查任务当前状态，若正在运行则先暂停 */
        boolean wasRunning = false;
        ScheduledFuture<?> scheduledTask = taskContainer.getScheduledTask(taskName, username);
        if (scheduledTask != null) {
            /* 记录原运行状态，修改后恢复 */
            wasRunning = true;
            /* 暂停任务（确保触发器停止） */
            scheduledTask.cancel(true);
            taskContainer.removeScheduledTask(taskName, username);
            LogUtil.info("任务[{}]正在运行，已临时暂停以更新调度策略", taskName);
        }

        try {
            /* 更新数据库中的调度参数 */
            updateTaskInfoScheduleParams(taskInfo, newScheduleType, cronExpression, interval, timeUnit);
            taskInfoMapper.updateById(taskInfo);
            LogUtil.info("任务[{}]调度策略已更新到数据库", taskName);

            /* 重建任务实例（基于新的调度参数） */
            AbstractScheduledTask taskInstance = createTaskInstance(taskInfo);

            /* 若原任务处于运行状态，按新策略重新启动 */
            if (wasRunning) {
                ScheduledFuture<?> newScheduledTask = scheduleTaskByType(taskInstance);
                taskContainer.addScheduledTask(taskName, username, newScheduledTask);
                LogUtil.info("任务[{}]已按新调度策略重新启动", taskName);
                return new TaskOperationResult(true, "调度策略更新成功，任务已重启", taskName);
            } else {
                /* 任务原处于暂停状态，仅更新配置不启动 */
                /* 清理可能的残留实例 */
                taskContainer.removeScheduledTask(taskName, username);
                LogUtil.info("任务[{}]调度策略更新成功（当前状态：暂停）", taskName);
                return new TaskOperationResult(true, "调度策略更新成功，任务保持暂停状态", taskName);
            }

        } catch (Exception e) {
            /* 发生异常时回滚事务，并尝试恢复原任务状态 */
            LogUtil.error("更新任务[{}]调度策略失败", null, taskName, e);
            if (wasRunning) {
                try {
                    /* 尝试恢复原任务运行 */
                    AbstractScheduledTask originalTask = createTaskInstance(taskInfo); // 使用更新前的taskInfo
                    ScheduledFuture<?> restoredTask = scheduleTaskByType(originalTask);
                    taskContainer.addScheduledTask(taskName, username, restoredTask);
                    LogUtil.warn("任务[{}]调度策略更新失败，已恢复原运行状态", taskName);
                } catch (Exception restoreEx) {
                    LogUtil.error("恢复任务[{}]原状态失败", null, taskName, restoreEx);
                }
            }
            return new TaskOperationResult(false, "调度策略更新失败：" + e.getMessage(), taskName);
        }
    }


    // ==================== 批量启动任务 ====================
    @Override
    @Transactional(rollbackFor = BlogException.class)
    public Map<String, TaskOperationResult> batchStartTasks(List<String> taskNames, String username) {
        return batchProcessTasks(
                taskNames,
                username,
                this::startTask,
                "批量启动"
        );
    }

    // ==================== 批量暂停任务 ====================
    @Override
    @Transactional(rollbackFor = BlogException.class)
    public Map<String, TaskOperationResult> batchPauseTasks(List<String> taskNames, String username) {
        return batchProcessTasks(
                taskNames,
                username,
                this::pauseTask,
                "批量暂停"
        );
    }

    // ==================== 批量销毁任务（逻辑删除） ====================
    @Override
    @Transactional(rollbackFor = BlogException.class)
    public Map<String, TaskOperationResult> batchDestroyTasks(List<String> taskNames, String username) {
        return batchProcessTasks(
                taskNames,
                username,
                (taskName, _) -> destroyTask(taskName, username, true),
                "批量销毁"
        );
    }

    // ==================== 批量恢复任务 ====================
    @Override
    @Transactional(rollbackFor = BlogException.class)
    public Map<String, TaskOperationResult> batchRestoreTasks(List<String> taskNames, String username) {
        return batchProcessTasks(
                taskNames,
                username,
                this::restoreTask,
                "批量恢复"
        );
    }

    // ==================== 一键启动所有任务 ====================
    @Override
    @Transactional(rollbackFor = BlogException.class)
    public Map<String, TaskOperationResult> startAllTasks(String username) {
        // 查询用户所有未删除且未运行的任务
        List<String> taskNames = taskInfoMapper.findByUsername(username).stream()
                .map(TaskInfo::getTaskName)
                .filter(taskName -> !taskContainer.isTaskRunning(taskName, username))
                .collect(Collectors.toList());

        LogUtil.info("用户[{}]一键启动所有任务，共[{}]个任务待启动", username, taskNames.size());
        return batchStartTasks(taskNames, username);
    }

    // ==================== 一键暂停所有任务 ====================
    @Override
    @Transactional(rollbackFor = BlogException.class)
    public Map<String, TaskOperationResult> pauseAllTasks(String username) {
        /* 查询用户所有运行中的任务 */
        List<String> runningTaskNames = taskContainer.getUserRunningTasks(username).stream()
                .map(AbstractScheduledTask::getTaskName)
                .collect(Collectors.toList());

        LogUtil.info("用户[{}]一键暂停所有任务，共[{}]个运行中任务", username, runningTaskNames.size());
        return batchPauseTasks(runningTaskNames, username);
    }

    // ==================== 批量处理核心逻辑（复用） ====================
    /**
     * 批量处理任务的通用逻辑，使用虚拟线程并发执行
     * @param taskNames 任务名称列表
     * @param username 用户名
     * @param processor 单个任务处理器（函数式接口，封装具体操作）
     * @param operationName 操作名称（用于日志）
     * @return 每个任务的操作结果
     */
    private Map<String, TaskOperationResult> batchProcessTasks(
            List<String> taskNames,
            String username,
            TaskProcessor processor,
            String operationName) {

        /* 参数校验 */
        if (taskNames == null || taskNames.isEmpty()) {
            LogUtil.warn("[{}]任务失败：任务名称列表为空", operationName);
            return Collections.emptyMap();
        }

        /* 去重处理（避免重复操作同一任务） */
        List<String> uniqueTaskNames = taskNames.stream().distinct().toList();
        LogUtil.info("开始[{}]用户[{}]的任务，共[{}]个（去重后）", operationName, username, uniqueTaskNames.size());

        /* 使用虚拟线程并发执行任务操作 */
        List<CompletableFuture<AbstractMap.SimpleEntry<String, TaskOperationResult>>> futures = uniqueTaskNames.stream()
                .map(taskName -> CompletableFuture.supplyAsync(() -> {
                    try {
                        /* 调用具体处理器（启动/暂停/销毁等）*/
                        TaskOperationResult result = processor.process(taskName, username);
                        return new AbstractMap.SimpleEntry<>(taskName, result);
                    } catch (Exception e) {
                        /* 单个任务异常不影响整体，单独记录错误结果 */
                        LogUtil.error("[{}]任务[{}]失败", null, operationName, taskName, e);
                        return new AbstractMap.SimpleEntry<>(
                                taskName,
                                new TaskOperationResult(false, operationName + "失败：" + e.getMessage(), taskName)
                        );
                    }
                }, virtualThreadPool))
                .toList().reversed();

        /* 等待所有任务完成并收集结果 */
        CompletableFuture.allOf(futures.toArray(new CompletableFuture[0])).join();

        /* 整理结果Map 保持输入顺序*/
        Map<String, TaskOperationResult> results = new LinkedHashMap<>();
        for (CompletableFuture<AbstractMap.SimpleEntry<String, TaskOperationResult>> future : futures) {
            Map.Entry<String, TaskOperationResult> entry = future.join();
            results.put(entry.getKey(), entry.getValue());
        }

        /* 统计成功/失败数量 */
        long successCount = results.values().stream().filter(TaskOperationResult::isSuccess).count();
        LogUtil.info("[{}]用户[{}]的任务完成：成功[{}]个，失败[{}]个",
                operationName, username, successCount, uniqueTaskNames.size() - successCount);

        return results;
    }

    // ==================== 函数式接口：单个任务处理器 ====================
    @FunctionalInterface
    private interface TaskProcessor {
        TaskOperationResult process(String taskName, String username) throws Exception;
    }

    /**
     * 验证调度参数合法性
     */
    private void validateScheduleParams(
            TaskType scheduleType,
            String cronExpression,
            Long interval,
            ChronoUnit timeUnit) {

        if (scheduleType == null) {
            throw new BlogException("调度类型不能为空");
        }

        switch (scheduleType) {
            case CRON:
                if (StringUtils.isEmpty(cronExpression)) {
                    throw new BlogException("CRON表达式不能为空");
                }
                /* 验证CRON表达式格式（使用Spring的CronExpression工具类） */
                if (!CronExpression.isValidExpression(cronExpression)) {
                    throw new BlogException("CRON表达式格式无效：" + cronExpression);
                }
                break;
            case FIXED_RATE:
            case FIXED_DELAY:
                if (interval == null || interval <= 0) {
                    throw new BlogException("时间间隔必须大于0");
                }
                if (timeUnit == null) {
                    throw new BlogException("时间单位不能为空");
                }
                /* 验证时间单位是否合法（仅支持常用单位） */
                Set<ChronoUnit> supportedUnits = Set.of(ChronoUnit.SECONDS, ChronoUnit.MINUTES,
                        ChronoUnit.HOURS, ChronoUnit.DAYS);
                if (!supportedUnits.contains(timeUnit)) {
                    throw new BlogException("不支持的时间单位：" + timeUnit);
                }
                break;
            default:
                throw new BlogException("不支持的调度类型：" + scheduleType);
        }
    }

    /**
     * 更新任务信息中的调度参数
     */
    private void updateTaskInfoScheduleParams(
            TaskInfo taskInfo,
            TaskType newScheduleType,
            String cronExpression,
            Long interval,
            ChronoUnit timeUnit) {

        /* 更新基础调度类型 */
        taskInfo.setScheduleType(newScheduleType.getCode());
        taskInfo.setUpdateTime(LocalDateTime.now());

        /* 根据调度类型更新对应参数（清除无关参数，避免混淆） */
        switch (newScheduleType) {
            case CRON -> {
                /* 清除固定间隔参数 */
                taskInfo.setTaskInterval(null);
                taskInfo.setCronExpression(cronExpression);
                taskInfo.setTimeUnit(null);
            }
            case FIXED_RATE, FIXED_DELAY -> {
                /* 清除CRON参数 */
                taskInfo.setCronExpression(null);
                taskInfo.setTaskInterval(interval);
                taskInfo.setTimeUnit(timeUnit.name());
            }
        }
    }

    /**
     * 根据任务类型调度任务（复用已有调度逻辑）
     */
    private ScheduledFuture<?> scheduleTaskByType(AbstractScheduledTask task) {
        TaskType type = task.getScheduleType();

        return switch (type) {
            case CRON -> scheduleCronTask(task);
            case FIXED_RATE -> scheduleFixedRateTask(task);
            case FIXED_DELAY -> scheduleFixedDelayTask(task);
        };
    }

    /**
     * 根据任务信息创建任务实例（重建任务实例核心方法）
     * 从数据库记录重建任务对象，恢复所有调度参数
     */
    private AbstractScheduledTask createTaskInstance(TaskInfo taskInfo) {
        try {
            /* 验证任务类信息 */
            if (StringUtils.isEmpty(taskInfo.getTaskClassName())) {
                throw new TaskOperationException("任务类名不存在，无法创建实例");
            }

            /* 反射创建任务实例 */
            Class<?> taskClass = Class.forName(taskInfo.getTaskClassName());
            AbstractScheduledTask taskInstance = (AbstractScheduledTask) taskClass.getDeclaredConstructor().newInstance();

            /* 恢复基本属性（使用反射设置私有字段） */
            setTaskField(taskInstance, "taskName", taskInfo.getTaskName());
            setTaskField(taskInstance, "username", taskInfo.getUsername());
            setTaskField(taskInstance, "taskDescription", taskInfo.getTaskDescription());

            /* 恢复调度参数 */
            TaskType scheduleType = TaskType.valueOf(taskInfo.getScheduleType());
            setTaskField(taskInstance, "scheduleType", scheduleType);

            /* 根据调度类型设置对应参数 */
            switch (scheduleType) {
                case CRON -> {
                    /* 清除可能的时间间隔参数，避免混淆 */
                    setTaskField(taskInstance, "taskInterval", null);
                    setTaskField(taskInstance, "cronExpression", taskInfo.getCronExpression());
                    setTaskField(taskInstance, "timeUnit", null);
                }
                case FIXED_RATE, FIXED_DELAY -> {
                    /* 清除可能的CRON参数，避免混淆 */
                    setTaskField(taskInstance, "cronExpression", null);
                    setTaskField(taskInstance, "taskInterval", taskInfo.getTaskInterval());
                    setTaskField(taskInstance, "timeUnit", ChronoUnit.valueOf(taskInfo.getTimeUnit()));
                }
                default -> throw new TaskOperationException("不支持的任务调度类型: " + scheduleType);
            }

            /* 将重建的实例添加到容器（覆盖旧实例） */
            taskContainer.addTask(taskInstance);
            LogUtil.info("任务[{}]实例已重建，调度类型: [{}]", taskInfo.getTaskName(), scheduleType);
            return taskInstance;

        } catch (ClassNotFoundException e) {
            throw new TaskOperationException("任务类不存在: " + taskInfo.getTaskClassName(), e);
        } catch (InstantiationException | IllegalAccessException | NoSuchMethodException | InvocationTargetException e) {
            throw new TaskOperationException("反射创建任务实例失败: " + taskInfo.getTaskName(), e);
        } catch (Exception e) {
            throw new TaskOperationException("任务参数设置失败，可能是类型不匹配: " + e.getMessage(), e);
        }
    }

    /**
     * 加载已存在的任务到内存容器（数据库已有记录时调用）
     */
    private void loadExistingTaskToContainer(AbstractScheduledTask task, TaskInfo existingTask) {
        String taskName = task.getTaskName();
        String username = task.getUsername();

        /* 添加到内存容器（覆盖可能存在的旧实例） */
        taskContainer.addTask(task);
        LogUtil.info("[任务加载] 任务[{}]已加载到内存容器（数据库已存在）", taskName);

        /* 若数据库中任务状态为“已激活”，自动恢复运行 */
        if (existingTask.getIsActive() == 1) {
            try {
                /* 检查是否已在运行（避免重复启动）*/
                if (!taskContainer.isTaskRunning(taskName, username)) {

                    /* 添加随机延迟（0 ~ 2）秒启动任务，避免同时启动多个任务 */
                    long delayMs = ThreadLocalRandom.current().nextLong(0, 2000);
                    Thread.sleep(delayMs);

                    ScheduledFuture<?> future = scheduleTaskByType(task);
                    taskContainer.addScheduledTask(taskName, username, future);
                    LogUtil.info("[任务恢复] 任务[{}]已自动恢复运行（延迟{}ms启动）（数据库状态：已激活）", taskName, delayMs);
                } else {
                    LogUtil.debug("[任务加载] 任务[{}]已在运行中，无需重复启动", taskName);
                }
            } catch (Exception e) {
                LogUtil.error("[任务恢复] 任务[{}]自动启动失败", null, taskName, e);
            }
        }

        /* 打印加载结果 */
        TaskType scheduleType = TaskType.valueOf(existingTask.getScheduleType());
        String paramsLog = buildTaskParamsLog(scheduleType, task);
        LogUtil.info("[任务加载] 任务[{}]加载完成 - {}", taskName, paramsLog);
    }

    /**
     * 构建任务参数日志（复用逻辑）
     */
    private String buildTaskParamsLog(TaskType scheduleType, AbstractScheduledTask task) {
        return switch (scheduleType) {
            case CRON -> String.format("CRON表达式：%s，状态：%s",
                    task.getCronExpression(), taskContainer.isTaskRunning(task.getTaskName(), task.getUsername()) ? "运行中" : "未运行");
            case FIXED_RATE, FIXED_DELAY ->
                    String.format("间隔：%d %s，类型：%s，状态：%s",
                            task.getTaskInterval(), task.getTimeUnit(), scheduleType,
                            taskContainer.isTaskRunning(task.getTaskName(), task.getUsername()) ? "运行中" : "未运行");
        };
    }

}

